﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//数组名就是数组⾸元素(第⼀个元素)的地址。
// 其实数组名就是数组⾸元素(第⼀个元素)的地址是对的，但是有两个例外：
// sizeof(数组名)，sizeof中单独放数组名，这⾥的数组名表⽰整个数组，计算的是整个数组的⼤⼩，
//单位是字节
// &数组名，这⾥的数组名表⽰整个数组，取出的是整个数组的地址（整个数组的地址和数组⾸元素
//的地址是有区别的）
//除此之外，任何地⽅使⽤数组名，数组名都表⽰⾸元素的地址。
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//
//	printf("&arr[0]   = %p\n", &arr[0]);
//	printf("&arr[0]+1 = %p\n", &arr[0]+1);
//
//	printf("arr       = %p\n", arr);
//	printf("arr+1     = %p\n", arr+1);
//
//	printf("&arr      = %p\n", &arr);
//	printf("&arr+1    = %p\n", &arr+1);
//
//
//	return 0;
//}
//
// 发现&arr[0]和&arr[0]+1相差4个字节，arr和arr+1 相差4个字节，是因为&arr[0] 和 arr 都是
//⾸元素的地址， + 1就是跳过⼀个元素
//
//int main()
//{
//	int arr[10] = { 0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	//输入
//	int i = 0;
//	int* p = arr;
//
//	for (i = 0; i < sz; i++)
//	{
//		//scanf("%d", p + i);//p+i 是下标为i元素的地址
//		scanf("%d", arr + i);
//	}
//	//输出
//	for (i = 0; i < sz; i++)
//	{
//		//printf("%d ", *(p + i));
//		//printf("%d ", *(arr + i));
//		printf("%d ", i[arr]);
//	}
//
//	return 0;
//}

//数组传参的时候，形参可以写成数组，也可以写成指针
//写成数组的形式，最简单，是为了方便理解，容易接受这种语法
//但是即使写成数组的形式，本质上还是指针
//        int* arr
//void test(int arr[])
//{
//	int sz2 = sizeof(arr) / sizeof(arr[0]);
//	printf("sz2 = %d\n", sz2);
//}
//
//void test(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//}
//void test(int* arr, int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		//printf("%d ", arr[i]);//arr[i] == *(arr+i)其实是相互之间等价的
//		printf("%d ", *(arr+i));//arr[i] == *(arr+i)
//	}
//}
//
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int sz1 = sizeof(arr) / sizeof(arr[0]);
//	printf("sz1 = %d\n", sz1);//10
//
//	test(arr, sz1);//arr 是数组名，数组名表示数组首元素的地址
//	//数组传参的本质，传递的是数组首元素的地址
//	//所以形参即使写成数组的形式，本质上也是一个指针变量
//	//
//	return 0;
//输入数组
void input(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		scanf("%d", arr + i);
	}
}
int count = 0;
////交换位置检测是不是冒泡数
////数组传参过来其实也是传地址过来 数组名就是首元素地址 可以用int* arr 也可以用int arr[]
void bobble_sort(int* arr, int sz)
{
	//几趟
	for (int i = 0; i < sz -1; i++)
	{
		int flag = 1;//假设不交换 顺序是满足的
		for (int j = 0; j < sz - 1 - i; j++)//每一趟内部的比较
		{
			count++;//比较了多少躺
			if (arr[j] > arr[j + 1])//如果是冒泡排序 前面比后边大 就交换
			{
				flag = 0;//不是有序的
				int tmp = 0;//进行交换
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}if (flag == 1)//第一趟发现都是有序就跳出循环 减少时间
		{
			break;
		}
					
	}
}
void print(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	input(arr,sz);
	bobble_sort(arr, sz);
	print(arr, sz);
	printf("\ncount = %d ", count);
	return 0;
}
////int main()
//{
//	int a = 10;
//
//	int* pa = &a; //pa是一级指针变量
//
//	int** ppa = &pa;//ppa就是二级指针变量
//
//	printf("%d\n", **ppa);
//	**ppa = 200;
//	printf("%d\n", a);//200
//
//
//	return 0;
//}
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = 30;
//	//int* pa = &a;
//	//int* pb = &b;
//	//int* pc = &c;
//	int* arr[3] = { &a, &b, &c };
//	//              0   1   2
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		printf("%d ", *(arr[i]));
//	}
//	return 0;
//}
//
//
//int main()
//{
//	int arr1[5] = { 1,2,3,4,5 };
//	int arr2[5] = { 2,3,4,5,6 };
//	int arr3[5] = { 3,4,5,6,7 };
//	
//	int* arr[] = { arr1, arr2, arr3 };
//
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", arr[i][j]);//*(*(arr+i)+j)
//		}
//		printf("\n");
//	}
//
//	return 0;
//}

//
//int main()
//{
//	char ch = 'w';
//	char* pc = &ch;
//	*pc = 'b';
//	printf("%c\n", *pc);
//
//	return 0;
//}


//int main()
//{
//	const char * p = "abcdef";//取得是 a 的地址 字符串首元素
//	printf("%c\n", *p);
//	printf("%s\n", p);//使用%s打印字符串的时候，只需要提供首字符的地址就行
//
//	//*p = 'q';
//
//	//char arr[] = "abcdef";
//	//char* p = arr;
//
//	return 0;
//}

//
//#include <stdio.h>
//输出2 3
//int main()
//{
//    char str1[] = "hello bit.";//比较的是数组名 不是同一个地址 所以不相等
//    char str2[] = "hello bit.";
//
//    const char* str3 = "hello bit.";这其实是一个地址 因为是同一个指针数组
//    const char* str4 = "hello bit.";
//
//    if (str1 == str2)
//        printf("str1 and str2 are same\n");//1
//    else
//        printf("str1 and str2 are not same\n");//2
//
//    if (str3 == str4)
//        printf("str3 and str4 are same\n");//3
//    else
//        printf("str3 and str4 are not same\n");//4
//
//    return 0;
//}

//int main()
//{
//	int arr[10] = {1,2,3,4,5};
//	int (*p) [10] = &arr;//p就是数组指针，p中存放的是数组的地址
//	//int(*)[10]  = int(*)[10]
//
//	//arr -- int*            arr+1 跳过4个字节
//	//&arr[0]  -- int*       &arr[0]+1跳过4个字节
//	//&arr -- int(*)[10]     &arr+1 跳过40个字节
//	//
//	int * ptr;
//	return 0;
//}
//指针数组是数组，存放的是指针(地址)
//数组指针
//
//类比 : 
//字符指针 - char* -指向字符的指针 - 字符指针变量中存放字符变量的地址 
// char ch = ‘w’
// char* pc = &ch
//整型指针 - int* -指向整型的指针 - 整型指针变量中存放整型变量的地址
// int a = 10; 
// int* p = &a;
//数组指针指向数组的指针数组指针变量中存放数组的地址
//                                           &数组名